<template>
  <div class="app-container">
    <!--工具栏-->
    <div class="head-container">
      <div v-if="crud.props.searchToggle">
        <!-- 搜索 -->
        <el-input v-model="query.keyword" class="filter-item" clearable placeholder="输入名称或者描述搜索" size="small"
                  style="width: 200px;" @keyup.enter.native="crud.toQuery"/>
        <rrOperation :crud="crud"/>
      </div>
      <crudOperation :permission="permission"/>
    </div>
    <!-- 表单渲染 -->
    <el-dialog :before-close="crud.cancelCU" :close-on-click-modal="false" :title="crud.status.title"
               :visible.sync="crud.status.cu > 0" append-to-body width="520px">
      <el-form ref="form" :inline="true" :model="form" :rules="rules" label-width="80px" size="small">
        <el-form-item label="角色编码" prop="code">
          <el-input v-model="form.code" style="width: 145px;"/>
        </el-form-item>
        <el-form-item label="角色名称" prop="name">
          <el-input v-model="form.name" style="width: 145px;"/>
        </el-form-item>
        <el-form-item label="角色权限" prop="permission">
          <el-input v-model="form.permission" style="width: 145px;"/>
        </el-form-item>
        <el-form-item label="数据范围" prop="dataScope">
          <el-select v-model="form.dataScope" placeholder="请选择数据范围" style="width: 145px" @change="changeScope">
            <el-option
                v-for="item in dateScopes"
                :key="item.value"
                :label="item.label"
                :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="角色级别" prop="level">
          <el-input-number v-model.number="form.level" :min="1" controls-position="right" style="width: 145px;"/>
        </el-form-item>
        <el-form-item v-if="form.dataScope === '5'" label="数据权限" prop="depts">
          <treeselect v-model="form.depts" :options="depts" multiple placeholder="请选择" style="width: 380px"/>
        </el-form-item>
        <el-form-item label="描述信息" prop="remark">
          <el-input v-model="form.remark" rows="5" style="width: 380px;" type="textarea"/>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="text" @click="crud.cancelCU">取消</el-button>
        <el-button :loading="crud.cu === 2" type="primary" @click="crud.submitCU">确认</el-button>
      </div>
    </el-dialog>
    <el-row :gutter="15">
      <!--角色管理-->
      <el-col :lg="16" :md="16" :sm="24" :xl="17" :xs="24" style="margin-bottom: 10px">
        <el-card class="box-card" shadow="never">
          <div slot="header" class="clearfix">
            <span class="role-span">角色列表</span>
          </div>
          <el-table ref="table" border v-loading="crud.loading" :data="crud.data" highlight-current-row style="width: 100%;"
                    @selection-change="crud.selectionChangeHandler" @current-change="handleCurrentChange">
            <el-table-column :render-header="crud.renderHeader" :selectable="checkboxT" type="selection" width="60"/>
            <el-table-column :render-header="crud.renderHeader" v-if="columns.visible('code')" label="编码" prop="code"/>
            <el-table-column :render-header="crud.renderHeader" v-if="columns.visible('name')" label="名称" prop="name"/>
            <el-table-column :render-header="crud.renderHeader" v-if="columns.visible('dataScope')" label="数据权限" prop="dataScope">
              <template slot-scope="scope">
                <el-tag>{{ dictName(dict.t_sys_role_data_scope,scope.row.dataScope)  }}</el-tag>
              </template>
            </el-table-column>
            <el-table-column :render-header="crud.renderHeader" v-if="columns.visible('permission')" label="角色权限" prop="permission"/>
            <el-table-column :render-header="crud.renderHeader" v-if="columns.visible('level')" label="角色级别" prop="level"/>
            <el-table-column :render-header="crud.renderHeader" v-if="columns.visible('status')" label="状态" prop="status" width="75px">
              <template slot-scope="scope">
                <el-tag v-if="scope.row.status == 0" type="danger">禁用</el-tag>
                <el-tag v-else type="success">启用</el-tag>
              </template>
            </el-table-column>
            <el-table-column :render-header="crud.renderHeader" v-if="columns.visible('remark')" :show-overflow-tooltip="true" label="描述" prop="remark"/>
            <el-table-column :render-header="crud.renderHeader" v-if="columns.visible('createTime')" :show-overflow-tooltip="true" label="创建日期"
                             prop="createTime" width="135px">
              <template slot-scope="scope">
                <span>{{ parseTime(scope.row.createTime) }}</span>
              </template>
            </el-table-column>
<!--            <el-table-column :render-header="crud.renderHeader" v-permission="['admin','roles:edit','roles:del']" align="center" fixed="right" label="操作"-->
<!--                             width="130px">-->
<!--              <template slot-scope="scope">-->
<!--                <udOperation-->
<!--                    v-if="scope.row.level >= level"-->
<!--                    :data="scope.row"-->
<!--                    :permission="permission"-->
<!--                />-->
<!--              </template>-->
<!--            </el-table-column>-->
          </el-table>
          <!--分页组件-->
          <pagination/>
        </el-card>
      </el-col>
      <!-- 菜单授权 -->
      <el-col :lg="8" :md="8" :sm="24" :xl="7" :xs="24">
        <el-card class="box-card" shadow="never">
          <div slot="header" class="clearfix">
            <el-tooltip class="item" content="选择指定角色分配菜单" effect="dark" placement="top">
              <span class="role-span">菜单分配</span>
            </el-tooltip>
            <el-button
                v-permission="['admin','roles:edit']"
                :disabled="showButton"
                :loading="menuLoading"
                icon="el-icon-check"
                size="mini"
                style="float: right; padding: 6px 9px"
                type="primary"
                @click="saveMenu"
            >保存
            </el-button>
          </div>
          <el-tree
            ref="menu"
            :data="menus"
            :default-checked-keys="menuIds"
            :props="defaultProps"
            show-checkbox
            :check-strictly="false"
            node-key="id"
          />
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import crudRoles from '@/api/system/role'
import {getDepts} from '@/api/system/dept'
import {tree} from '@/api/system/menu'
import CRUD, {crud, form, header, presenter} from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import udOperation from '@crud/UD.operation'
import pagination from '@crud/Pagination'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'

// crud交由presenter持有
const defaultCrud = CRUD({title: '角色', url: 'api/sysRole', sort: 'level,asc', crudMethod: {...crudRoles}})
const defaultForm = {
  id: null,
  code: null,
  name: null,
  depts: [],
  remark: null,
  dataScope: 1,
  level: 3,
  permission: null
}
export default {
  name: 'Role',
  components: {Treeselect, pagination, crudOperation, rrOperation, udOperation},
  mixins: [presenter(defaultCrud), header(), form(defaultForm), crud()],
  dicts: [ 't_sys_role_data_scope'],
  data() {
    return {
      defaultProps: {children: 'children', label: 'name', code: 'code'},
      dateScopes: [{label: '全部', value: 1}, {label: '部门', value: 2}, {label: '部门及以下', value: 3}, {
        label: '本人',
        value: 4
      }, {label: '自定义', value: 5}],
      level: 3,
      currentId: 0, menuLoading: false, showButton: false,
      menus: [], menuIds: [], depts: [],
      permission: {
        add: ['admin', 'sysRole:add'],
        edit: ['admin', 'sysRole:edit'],
        del: ['admin', 'sysRole:del'],
        import: ['admin', 'sysRole:import'],
        export: ['admin', 'sysRole:export']
      },
      rules: {
        name: [
          {required: true, message: '请输入名称', trigger: 'blur'}
        ],
        code: [
          {required: true, message: '请输入角色编码', trigger: 'blur'}
        ],
        permission: [
          {required: true, message: '请输入权限', trigger: 'blur'}
        ]
      }
    }
  },
  created() {
    this.getMenus()
    crudRoles.getLevel().then(res => {
      this.level = res.data.level
    })
    this.$nextTick(() => {
      this.crud.toQuery()
    })
  },
  methods: {
    [CRUD.HOOK.afterRefresh]() {
      this.$refs.menu.setCheckedKeys([])
    },
    // 编辑前
    [CRUD.HOOK.beforeToEdit](crud, form) {
      if (form.dataScope === '自定义') {
        this.getDepts()
      }
      const depts = []
      form.depts.forEach(function (dept, index) {
        depts.push(dept.id)
      })
      form.depts = depts
    },
    // 提交前做的操作
    [CRUD.HOOK.afterValidateCU](crud) {
      if (crud.form.dataScope === '自定义' && crud.form.depts.length === 0) {
        this.$message({
          message: '自定义数据权限不能为空',
          type: 'warning'
        })
        return false
      } else if (crud.form.dataScope === '自定义') {
        const depts = []
        crud.form.depts.forEach(function (data, index) {
          const dept = {id: data}
          depts.push(dept)
        })
        crud.form.depts = depts
      } else {
        crud.form.depts = []
      }
      return true
    },
    [CRUD.HOOK.afterAddError](crud) {
      this.afterErrorMethod(crud)
    },
    [CRUD.HOOK.afterEditError](crud) {
      this.afterErrorMethod(crud)
    },
    getNodeChildren(node,list){
      if (node.children){
        for (let i =0;i<node.children.length;i++){
          list = this.getNodeChildren(node.children[i],list)
        }
        return list
      }else {
        list.push(node.id)
        return list
      }
    },



    afterErrorMethod(crud) {
      const depts = []
      crud.form.depts.forEach(function (dept, index) {
        depts.push(dept.id)
      })
      crud.form.depts = depts
    },
    // 获取所有菜单
    getMenus() {
      tree().then(res => {
        this.menus = res.data
      })
    },


    getNode(curObj, objStatus, list) {
      let menuIds = this.menuIds
      if (objStatus) {
        const parentNode = this.$refs.menu.getNode(curObj).parent
        if (parentNode.key !== undefined) {
          this.$refs.menu.setChecked(parentNode, true)
        } else {
          const _this = this
          let childrenList = []
          if (curObj.children && curObj.children.length > 0) {
            curObj.children.map((item) => {
              menuIds.push(item.id)
              if (item.children) {
                childrenList = childrenList.concat(item.children)
              }
            })
          }
          if (childrenList && childrenList.length > 0) {
            childrenList.map((resA) => {
              menuIds.push(resA.id)
            })
          }
          _this.menuIds = menuIds.concat()
        }
      } else {
        // 当前节点取消选中，所有子节点取消选中
        if (curObj.children !== undefined) {
          curObj.children.forEach((item, i) => {
            this.$refs.menu.setChecked(item, false, true)
          })
        }
        return false
      }
    },

    // 触发单选
    handleCurrentChange(val) {
      if (val) {
        const _this = this
        // 清空菜单的选中
        this.$refs.menu.setCheckedKeys([])
        // 保存当前的角色id
        this.currentId = val.id
        this.showButton = val.id === 1?false:val.level>= this.level
        // 初始化
        this.menuIds = []
        // 菜单数据需要特殊处理
        // val.menuList.forEach(function (data, index) {
        //   _this.menuIds.push(data.id)
        // })
        for (let i = 0;i<val.menuList.length;i++){
          this.menuIds = this.getNodeChildren(val.menuList[i],this.menuIds)
        }
        console.log(this.menuIds)
      }
    },

    // 保存菜单
    saveMenu() {
      this.menuLoading = true
      const role = {id: this.currentId, menuList: []}
      // 得到半选的父节点数据，保存起来
      this.$refs.menu.getHalfCheckedNodes().forEach(function (data, index) {
        const menu = {id: data.id}
        role.menuList.push(menu)
      })
      // 得到已选中的 key 值
      this.$refs.menu.getCheckedKeys().forEach(function (data, index) {
        // console.log("data2",data)
        const menu = {id: data}
        role.menuList.push(menu)
      })
      crudRoles.editMenu(role).then(res => {
        this.crud.notify('保存成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
        this.menuLoading = false
        this.update()
        this.crud.refresh()
      }).catch(err => {
        this.menuLoading = false
        console.log(err.response.data.message)
      })
    },
    // 改变数据
    update() {
      // 无刷新更新 表格数据
      crudRoles.get(this.currentId).then(res => {
        for (let i = 0; i < this.crud.data.length; i++) {
          if (res.id === this.crud.data[i].id) {
            this.crud.data[i] = res
            break
          }
        }
      })
    },
    // 获取部门数据
    getDepts() {
      getDepts({enabled: true}).then(res => {
        this.depts = res
      })
    },
    // 如果数据权限为自定义则获取部门数据
    changeScope() {
      if (this.form.dataScope === '自定义') {
        this.getDepts()
      }
    },
    checkboxT(row, rowIndex) {
      return row.level <= this.level
    }
  }
}
</script>

<style lang="scss" rel="stylesheet/scss">
.role-span {
  font-weight: bold;
  color: #303133;
  font-size: 15px;
}
</style>

